#include "SemanticNodeBlockCreate.h"

#include "main2.h"


/**
 *  @fn	SemanticNodeBlockCreate::SemanticNodeBlockCreate(const SyntaxTreeNode *createNodeParent,
 *  	SemanticNode *parent)
 * 
 *  @brief	Constructor.
 * 
 *  @author	Nikola Novak
 *  @date	6/26/2009
 * 
 *  @param	createNodeParent	If non-null, the create node parent.
 *  @param	parent				If non-null, the parent.
 * 
 *  @return	.
 */
SemanticNodeBlockCreate::SemanticNodeBlockCreate(const SyntaxTreeNode *createNodeParent, SemanticNode *parent) : SemanticNode(parent), LabeledNode(createNodeParent->Nodes->GetData(0)) {
	transList = false; deviation = false;
	const SyntaxTreeNode *reqNode = createNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	if (reqNode->Nodes->GetData(2)->Nodes->GetCount() == 0) name = "Transaction";
	else {
		name = flattenNamePeriodAdd(*reqNode->Nodes->GetData(2)->Nodes->GetData(0));
		transList = (reqNode->Nodes->GetData(2)->Production == Gr_GenerateTransactions__Name_spLPar_TransList_spRPar);
	}
	upto = (reqNode->Nodes->GetData(1)->Nodes->GetCount() > 0);
	after = (reqNode->Nodes->GetData(3)->Nodes->GetCount() > 0);
	every = (reqNode->Nodes->GetData(4)->Nodes->GetCount() > 0);
	if (!every) {
	 if (!after) {
	 	// ToDo: report error - nema ni bloka after ni every
	 }
	 if (!upto) {
	 	// ToDo: report error - nema ni bloka upto ni every
	 }
	} else deviation = (reqNode->Nodes->GetData(4)->Nodes->GetData(2)->Nodes->GetCount() > 0);
	sendTo = (reqNode->Nodes->GetData(5)->Nodes->GetCount() > 0);
	if (reqNode->Nodes->GetData(5)->Production == Gr_SendTo__send_to_Name)
		sendToName = flattenNamePeriodAdd(*reqNode->Nodes->GetData(5)->Nodes->GetData(2));
}
/**
 *  @fn	void SemanticNodeBlockCreate::setUptoExpression(SemanticNodeExpression *upto)
 * 
 *  @brief	Sets a upto expression. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @param	upto	If non-null, the upto.
 */
void SemanticNodeBlockCreate::setUptoExpression(SemanticNodeExpression *upto) {
	uptoExpression = upto;
}
/**
 *  @fn	void SemanticNodeBlockCreate::setAfterExpression(SemanticNodeExpression *after)
 * 
 *  @brief	Sets an after expression. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @param	after	If non-null, the after.
 */
void SemanticNodeBlockCreate::setAfterExpression(SemanticNodeExpression *after) {
	afterExpression = after;
}
/**
 *  @fn	void SemanticNodeBlockCreate::setEveryExpression(SemanticNodeExpression *every)
 * 
 *  @brief	Sets an every expression. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @param	every	If non-null, the every.
 */
void SemanticNodeBlockCreate::setEveryExpression(SemanticNodeExpression *every) {
	everyExpression = every;
}
/**
 *  @fn	void SemanticNodeBlockCreate::setDeviationExpression(SemanticNodeExpression *deviation)
 * 
 *  @brief	Sets a deviation expression. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @param	deviation	If non-null, the deviation.
 */
void SemanticNodeBlockCreate::setDeviationExpression(SemanticNodeExpression *deviation) {
	deviationExpression = deviation;
}
/**
 *  @fn	void SemanticNodeBlockCreate::addTransaction(std::string name,
 *  	SemanticNodeExpression *probability)
 * 
 *  @brief	Adds a transaction to 'probability'. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @param	name		The name.
 *  @param	probability	If non-null, the probability.
 */
void SemanticNodeBlockCreate::addTransaction(std::string name, SemanticNodeExpression *probability) {
	pair<std::string, SemanticNodeExpression *> newTrans(name, probability);
	transactionList.push_back(newTrans);
}
/**
 *  @fn	bool SemanticNodeBlockCreate::hasUpto(void)
 * 
 *  @brief	Query if this object has upto. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @return	true if upto, false if not.
 */
bool SemanticNodeBlockCreate::hasUpto(void) {
	return upto;
}
/**
 *  @fn	bool SemanticNodeBlockCreate::hasAfter(void)
 * 
 *  @brief	Query if this object has after. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @return	true if after, false if not.
 */
bool SemanticNodeBlockCreate::hasAfter(void) {
	return after;
}
/**
 *  @fn	bool SemanticNodeBlockCreate::hasEvery(void)
 * 
 *  @brief	Query if this object has every. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @return	true if every, false if not.
 */
bool SemanticNodeBlockCreate::hasEvery(void) {
	return every;
}
/**
 *  @fn	bool SemanticNodeBlockCreate::hasDeviation(void)
 * 
 *  @brief	Query if this object has deviation. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @return	true if deviation, false if not.
 */
bool SemanticNodeBlockCreate::hasDeviation(void) {
	return deviation;
}
/**
 *  @fn	bool SemanticNodeBlockCreate::hasTransactionList(void)
 * 
 *  @brief	Query if this object has transaction list. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @return	true if transaction list, false if not.
 */
bool SemanticNodeBlockCreate::hasTransactionList(void) {
	return transList;
}
/**
 *  @fn	bool SemanticNodeBlockCreate::hasSendTo(void)
 * 
 *  @brief	Query if this object has send to. 
 * 
 *  @author	Nikola Novak
 *  @date	8/12/2009
 * 
 *  @return	true if send to, false if not.
 */
bool SemanticNodeBlockCreate::hasSendTo(void) {
	return sendTo;
}
/**
 *  @fn	std::string SemanticNodeBlockCreate::toDebugString(int tab)
 * 
 *  @brief	Converts a tab to a debug string. 
 * 
 *  @author	Nikola Novak
 *  @date	6/25/2009
 * 
 *  @param	tab	The tab.
 * 
 *  @return	This object as a std::string.
 */
std::string SemanticNodeBlockCreate::toDebugString(int tab) {
	std::ostringstream res;
	for (int i = 0; i < tab; i++)	res << DEBUG_STRING_RAZMAK;
	res << getLabelsDebugString() << ": create ";
	if (!upto) res << "upto infinity ";
	else {
		res << "upto " << std::endl << ((SemanticNode *)uptoExpression)->toDebugString(tab + 1);
		for (int i = 0; i < tab; i++)	res << DEBUG_STRING_RAZMAK;
	}
	res << name << "(" << std::endl;
	if (transList) {
		for (std::vector<std::pair<std::string, SemanticNodeExpression *> >::iterator i = transactionList.begin(); i != transactionList.end(); ++i) {
			for (int t = 0; t < tab; t++)	res << DEBUG_STRING_RAZMAK;
			res << (*i).first << ":" << std::endl;
			res << ((SemanticNode *)(*i).second)->toDebugString(tab + 1);
		}
	}
	for (int i = 0; i < tab; i++)	res << DEBUG_STRING_RAZMAK;
	res << ") ";
	if (!after) res << "after - ";
	else {
		res << "after " << std::endl << ((SemanticNode *)afterExpression)->toDebugString(tab + 1);
		for (int i = 0; i < tab; i++)	res << DEBUG_STRING_RAZMAK;
	}
	if (!every) res << "every - ";
	else {
		res << "every " << std::endl << ((SemanticNode *)everyExpression)->toDebugString(tab + 1);
		for (int i = 0; i < tab; i++)	res << DEBUG_STRING_RAZMAK;
	}
	if (!deviation) res << "+- - " << std::endl;
	else {
		res << "+- " << std::endl << ((SemanticNode *)deviationExpression)->toDebugString(tab + 1);
		for (int i = 0; i < tab; i++)	res << DEBUG_STRING_RAZMAK;
	}
	if (!sendTo) res << "and resume with next block" << std::endl;
	else res << "send to " << sendToName << std::endl;
	return res.str();
}
